#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <vector>
#include <unistd.h> 

#include "conf.h"
#include "my_string.h"

//静态成员赋值
CConfig *CConfig::m_instance = nullptr;
std::mutex CConfig::m_mutex;

// 构造函数
CConfig::CConfig(){}

// 析构函数（释放容器内的东西）
CConfig::~CConfig(){
    std::vector<LPCConfItem>::iterator pos;// 定义迭代器
    for(pos = m_ConfigItemList.begin(); pos != m_ConfigItemList.end(); ++pos){
        delete (*pos);
    }
    m_ConfigItemList.clear();
}

//加载配置文件
bool CConfig::Load(const char *pconfName){
    FILE *fp;
    fp = fopen(pconfName,"r");
    if(fp == NULL){
        return false;
    }

    // 保存每一行的缓冲区（每一行限制500字符内）
    char linebuf[501];

    // 遍历读取配置文件内容
    while (!feof(fp))
    {
        // 读取字符串，500字符
        if(fgets(linebuf, 500, fp) == NULL){
            continue;// 不足就继续循环
        }

        if(linebuf[0] == 0){
            continue;// 说明缓冲区没内容（可能上一次刚好读完）
        }

        // 也跳过注释的行(特殊首字符)
        if(linebuf[0] == ';' || linebuf[0] == ' ' || linebuf[0] == '#' || linebuf[0] == '\t' || linebuf[0] == '\n'){
            continue;
        }

        // 开始处理每一行（放置标签用于goto跳转）
        lblprocstring:

        // 去掉每一行末尾的换行、回车和空格
        if(strlen(linebuf) > 0){
            if(linebuf[strlen(linebuf) -1] == '\n' || linebuf[strlen(linebuf) -1] == '\r' || linebuf[strlen(linebuf) -1] == ' '){
                linebuf[strlen(linebuf) -1] = 0;
                goto lblprocstring;// 返回再进行判断，持续去掉末尾
            }
        }

        // 如果此时已经空了，或者是[开头的，也不处理
        if(linebuf[0] == 0 || linebuf[0] == '['){
            continue;
        }

        // 此时说明本行确实是有效的，形如xxx = xxx，开始处理
        char *ptmp = strchr(linebuf, '=');// 获取第一次出现=的地址
        if(ptmp != NULL){
            LPCConfItem p_confitem = new CConfItem;// 新的配置项
            memset(p_confitem, 0, sizeof(CConfItem));
            strncpy(p_confitem->ItemName, linebuf, (int)(ptmp-linebuf));// 等号左侧是名称
            strcpy(p_confitem->ItemContent, ptmp+1);// 等号右侧是内容

            // 去除首尾空格
            Rtrim(p_confitem->ItemName);
			Ltrim(p_confitem->ItemName);
			Rtrim(p_confitem->ItemContent);
			Ltrim(p_confitem->ItemContent);

            m_ConfigItemList.push_back(p_confitem);// 存入容器
        }
    }
    
    fclose(fp);// 关闭文件
    return true;
}

//根据ItemName获取配置信息字符串，不修改不用互斥
const char *CConfig::GetString(const char *p_itemname){
    std::vector<LPCConfItem>::iterator pos;
    for(pos = m_ConfigItemList.begin(); pos != m_ConfigItemList.end(); ++pos){
        // 不按大小写进行字符串比较
        if(strcasecmp((*pos)->ItemName,p_itemname) == 0){
            return (*pos)->ItemContent;
        }
    }
    return NULL;
}

//根据ItemName获取数字类型配置信息，不修改不用互斥
int CConfig::GetIntDefault(const char *p_itemname,const int def){
    std::vector<LPCConfItem>::iterator pos;	
	for(pos = m_ConfigItemList.begin(); pos !=m_ConfigItemList.end(); ++pos){	
		if(strcasecmp((*pos)->ItemName, p_itemname) == 0){
            return atoi((*pos)->ItemContent);// 转换为整数后返回
        }	
	}
	return def;
}